<?php
namespace Swoole\Thrift;


use Thrift\Exception\TTransportException;
use Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\TPhpStream;
use Thrift\Transport\TBufferedTransport;
use Thrift\TMultiplexedProcessor;
use Thrift\Server\TServer;
use Thrift\Exception\TException;
use Swoole\Registry\ThriftServerRegistry;
use Common\Log;
use Swoole\Handler\ThriftServiceHandler;
use Swoole\Service\ThriftServiceProcessor;
use Common\FileUtil;

class SwooleHttpServer extends TServer
{

    private $config;
    public static $thriftServer;
    private $address;
    private $host;
    private $port;
    private $services = array();
    private $genDir;
    private $handlerDir;
    public function __construct($config)
    {
        $this->config = $config;
        $address = $this->config['address'];
        $this->address = parse_url($address);
        if(empty($this->address['host']) == true || empty($this->address['port']) == true){
            exit('config error, address is error!');
        }
        $this->initService($this->config);
     
       
    }
    function initService($config){
        $genDir = $config['gen-php'];
        $handlerDir = $config['handler'];
        $handlerFiles = FileUtil::getPathFiles($handlerDir);
        $handlerClasses = array();
        if(count($handlerFiles)){
            foreach ($handlerFiles as $file){
                $fileClass = substr($file, strlen($handlerDir), strlen($file) - strlen($handlerDir) - 4);
                $fileClass = \str_replace(DIRECTORY_SEPARATOR, '\\', $fileClass);
                $fileInfo = pathinfo($file);
                $className = $fileInfo['filename'];
                $handlerClasses[$className] = $fileClass;
            }
        }
        $genFiles = FileUtil::getPathFiles($genDir);
        if(count($genFiles) > 0){
            foreach($genFiles as $file){
                $service_class = substr($file, strlen($genDir),  strlen($file) - strlen($genDir) - 4);
                $service_class = \str_replace(DIRECTORY_SEPARATOR, '\\', $service_class);
                $info = pathinfo($file);
                $serviceName = $info['filename'];
                $processor_class = $service_class . 'Processor';
                if(isset($handlerClasses[$serviceName.'Handler']) == true){
                    $handler_class = $handlerClasses[$serviceName.'Handler'];
                    $handler = new $handler_class();
                    $processor = new $processor_class($handler);
                    $this->services[$serviceName] = $processor;
                }
            }
        }
    
    
    }
    
   
    
    function onStart()
    {
        echo "ThriftServer Start\n";
    }

    function notice($log)
    {
        echo $log . "\n";
    }

    /**
     * Serves the server.
     * This should never return
     * unless a problem permits it to do so or it
     * is interrupted intentionally
     *
     * @abstract
     *
     * @return void
     */
    public function serve()
    {
        echo "server ready====\n";
//         $address = $this->config['address'];
//         $this->address = parse_url($address);
        //var_dump($this->address);
        if (empty($this->address['host']) == true && empty($this->address['port']) == true) {
            throw new TException('error, address is empty\n');
        }

        $serv = new \swoole_http_server($this->address['host'], $this->address['port']);

        $config = $this->config;

        $serv->on('start', array($this, 'onHttpStart'));
        $serv->on('close', array($this, 'onHttpClose'));

        $serv->on('Request', array(
            $this,
            'onHttpRequest'
        ));
        $serv->start();
        Log::info("server start====");
    }

    public function onHttpStart($serv){
        Log::info('pid:'.posix_getpid().'server start at '.$this->address['host'].":".$this->address['port']);
        $thriftServerRegistry = new ThriftServerRegistry($this->config);
        $thriftServerRegistry->connect();
    }
    public function onHttpClose($serv, $fd){
        $fdinfo = $serv->connection_info($fd);
        $remote_ip = $fdinfo["remote_ip"];
        $remote_port = $fdinfo["remote_port"];
        echo "Client $remote_ip:$remote_port Close.\n";
    }
    public function onHttpRequest($request, $response)
    {
        $raw = $request->rawContent();
        $transport = new TBufferedTransport(new HttpStream(TPhpStream::MODE_R | TPhpStream::MODE_W, $raw, $response));
        $protocol = new TBinaryProtocol($transport, true, true);
        $tMultiplexedProcessor = new TMultiplexedProcessor();
      
        foreach($this->services as $serviceName=>$processor){
            $tMultiplexedProcessor->registerProcessor($serviceName, $processor);
        }
        
//         $handler = new ThriftServiceHandler();
//         $processor = new ThriftServiceProcessor($handler);
//         $tMultiplexedProcessor->registerProcessor('ThriftService', $processor);
        
        $transport->open();
        $tMultiplexedProcessor->process($protocol, $protocol);
        $transport->close();
    }
   
    /**
     * Stops the server serving
     *
     * @abstract
     *
     * @return void
     */
    public function stop(){
        
    }
}

?>